package com.wetool.wechat.service;

import com.wetool.wechat.entity.WechatAccountRelation;
import com.wetool.wechat.entity.WechatMerchantRelation;
import com.wetool.wechat.jpa.WechatAccountRelationRepo;
import com.wetool.wechat.jpa.WechatMerchantRelationRepo;
import com.wetool.wechat.model.SceneValue;
import com.wetool.wechat.model.official.EventType;
import com.wetool.wechat.model.official.message.AbstractMessage;
import com.wetool.wechat.model.official.message.reply.TextMessage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.Map;

@Service
public class EventHandlerService {
    private static final Logger LOGGER = LoggerFactory.getLogger(EventHandlerService.class);

    @Autowired
    private WechatOfficialService wechatOfficialService;

    @Autowired
    private WechatAccountRelationRepo wechatAccountRelationRepo;

    @Autowired
    private WechatMerchantRelationRepo wechatMerchantRelationRepo;

    public AbstractMessage dispatchEvent(Map<String, Object> xmlElements) {
        EventType eventType = null;
        String event = (String) xmlElements.get("Event");
        try {
            eventType = EventType.valueOf(event);
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
            LOGGER.error("无法处理的微信事件,请查阅微信开发者平台更新日志，是否新增事件,{}", event);
            return null;
        }
        switch (eventType) {
            case subscribe:
                LOGGER.info("接收到订阅事件");
                //TODO
                return this.subscribeEventHandler(xmlElements);
            case unsubscribe:
                LOGGER.info("接收到取消订阅事件");
                //TODO
                return this.unsubscribeEventHandler(xmlElements);
            case SCAN:
                LOGGER.info("接收到扫码事件");
                return this.scanEventHandler(xmlElements);
            case LOCATION:
                LOGGER.info("接收到地理位置事件");
                return this.locationEventHandler(xmlElements);
            case CLICK:
                LOGGER.info("接收到点击自定义菜单事件");
                return this.clickEventHandler(xmlElements);
            case VIEW:
                LOGGER.info("接收到显示自定义菜单事件");
                return this.viewEventHandler(xmlElements);
        }

        return null;
    }

    private AbstractMessage viewEventHandler(Map<String, Object> xmlElements) {
        //TODO
        return null;
    }

    private AbstractMessage clickEventHandler(Map<String, Object> xmlElements) {
        //TODO
        return null;
    }

    private AbstractMessage locationEventHandler(Map<String, Object> xmlElements) {
        //TODO
        return null;
    }

    private AbstractMessage scanEventHandler(Map<String, Object> xmlElements) {
        //TODO

        String eventKey = (String) xmlElements.get("EventKey");
        //服务商场景扫码流程
        String openId = (String) xmlElements.get("FromUserName");//获取oepnId
        String ticket = (String) xmlElements.get("Ticket");//获取oepnId

        if (eventKey.contains(SceneValue.REGISTER_MERCHANT.getName())) {
            //商家进件注册扫码流程(微信场景码)
            this.merchantScanQr(openId, ticket);
        } else if (eventKey.contains(SceneValue.REGISTER_SERVICE_PROVIDER.getName())) {
            //服务商注册/登录扫码流程(微信场景码)
            WechatAccountRelation account = this.wechatAccountRelationRepo.findByOfficialOpenId(openId);
            if (account != null) {
                account.bindTicket(ticket);
                this.wechatAccountRelationRepo.save(account);
            } else {
                this.sceneQrCodeSubscribeEvent(openId, ticket);
            }
        }
        return null;
    }

    private void merchantScanQr(String openId, String ticket) {
        WechatMerchantRelation relation = this.wechatMerchantRelationRepo.findOneByTicket(ticket);
        if (relation == null) {
            return;
        }
        String unionId = this.wechatOfficialService.getUnionIdByOpenId(openId);

        relation.bindingWechatAccount(unionId, openId);
        this.wechatMerchantRelationRepo.save(relation);
    }

    private AbstractMessage unsubscribeEventHandler(Map<String, Object> xmlElements) {

        String openId = (String) xmlElements.get("FromUserName");//获取oepnId

        WechatAccountRelation accountRelation = this.wechatAccountRelationRepo.findByOfficialOpenId(openId);//获取账户关系
        if (accountRelation == null) { //如果当前openId不存在账户关系，则查找unionId
/*            String unionId = this.wechatOfficialService.getUnionIdByOpenId(openId);
            accountRelation = this.wechatAccountRelationRepo.findOne(unionId);
            if (accountRelation == null) {//如果当前unionId不存在账户关系 ，则当前订阅帐号不属于微兔体系的用户，而是普通消费者。
                return; //TODO 发送欢迎消息？？？
            } else {
                //如果存在账户关系，则补全公众号关系
                accountRelation.unbindOfficialOpenId();
                this.wechatAccountRelationRepo.save(accountRelation);
            }*/
        } else {
            /*if (accountRelation.getOfficialOpenId() != null) {
                accountRelation.unbindOfficialOpenId();
                this.wechatAccountRelationRepo.save(accountRelation);
            }*/
            accountRelation.unbindOfficialOpenId();
            this.wechatAccountRelationRepo.save(accountRelation);
        }

        //TODO
        return null;
    }

    /**
     * 处理订阅消息
     *
     * @param xmlElements
     */
    private AbstractMessage subscribeEventHandler(Map<String, Object> xmlElements) {

        String openId = (String) xmlElements.get("FromUserName");//获取oepnId


        String ticket = (String) xmlElements.get("Ticket");

        if (StringUtils.isEmpty(ticket)) {
            //非带参数二维码扫码关注事件
            this.normalSubscribeEvent(openId);
        } else {
            //带参数二维码扫码关注事件
            String eventKey = (String) xmlElements.get("EventKey");

            if (eventKey.contains(SceneValue.REGISTER_MERCHANT.getName())) {
                this.sceneQrCodeSubscribeEventForMerchant(openId, ticket);
            } else if (eventKey.contains(SceneValue.REGISTER_SERVICE_PROVIDER.getName())) {
                this.sceneQrCodeSubscribeEvent(openId, ticket);
            }
        }
        TextMessage textMessage = new TextMessage();

        textMessage.setToUserName(openId);
        textMessage.setFromUserName((String) xmlElements.get("ToUserName"));
        textMessage.setCreateTime(System.currentTimeMillis() / 1000L);
        textMessage.setContent("嗨，你终于来了/:circle微兔科技的小伙伴们欢迎你！一起来了解一下我们的公司吧/:rose");

        return textMessage;
    }

    private void sceneQrCodeSubscribeEventForMerchant(String openId, String ticket) {
        this.merchantScanQr(openId, ticket);
    }

    /**
     * 公众订阅事件：微信自定义场景二维码入口
     * <p>
     * 执行用户注册流程
     *
     * @param openId 订阅用户公众号openId
     * @param ticket
     */
    private void sceneQrCodeSubscribeEvent(String openId, String ticket) {
        //如果ticket已经被记录过，则不操作，一个ticket只允许记录一次
        WechatAccountRelation byTicket = this.wechatAccountRelationRepo.findByTicket(ticket);
        if (byTicket != null) {
            return;
        }

        WechatAccountRelation accountRelation = this.wechatAccountRelationRepo.findByOfficialOpenId(openId);
        if (accountRelation == null) {
            String unionId = this.wechatOfficialService.getUnionIdByOpenId(openId);
            accountRelation = this.wechatAccountRelationRepo.findOne(unionId);
            if (accountRelation == null) {
                accountRelation = new WechatAccountRelation(unionId, null);
            }
        }

        accountRelation.bindOfficialOpenId(openId);
        accountRelation.bindTicket(ticket);
        this.wechatAccountRelationRepo.save(accountRelation);
    }

    /**
     * 公众订阅事件: 普通关注入口
     *
     * @param openId 订阅用户的公众OpenId
     */
    private void normalSubscribeEvent(String openId) {
        WechatAccountRelation accountRelation = this.wechatAccountRelationRepo.findByOfficialOpenId(openId);//获取账户关系

        //如果当前openId不存在账户关系，则查找unionId
        if (accountRelation == null) {
            String unionId = this.wechatOfficialService.getUnionIdByOpenId(openId);
            accountRelation = this.wechatAccountRelationRepo.findOne(unionId);
            //如果当前unionId不存在账户关系 ，则当前订阅帐号不属于微兔体系的用户，而是普通消费者。
            if (accountRelation == null) {
                return; //TODO 发送欢迎消息？？？
            } else {
                //如果存在账户关系，则补全公众号关系，绑定公众号openId
                accountRelation.bindOfficialOpenId(openId);
                this.wechatAccountRelationRepo.save(accountRelation);
            }
        }
        /*else {
            //
            if (accountRelation.getOfficialOpenId() == null) {
                accountRelation.bindOfficialOpenId(openId);
                this.wechatAccountRelationRepo.save(accountRelation);
            }
        }*/
    }
}
